package cn.lf.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.lf.constant.ResponseCodeEnum;
import cn.lf.constant.UserStatusEnum;
import cn.lf.constant.UserTypeEnum;
import cn.lf.dto.LoginUserInfoDTO;
import cn.lf.dto.system.*;
import cn.lf.entity.ShopInfo;
import cn.lf.entity.SysUser;
import cn.lf.exception.SelfException;
import cn.lf.mapper.ShopInfoMapper;
import cn.lf.mapper.SysUserMapper;
import cn.lf.service.ISystemService;
import cn.lf.utils.JwtUtils;
import cn.lf.utils.PasswordUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author guoyy
 */
@Service
public class SystemServiceImpl implements ISystemService {

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private ShopInfoMapper shopInfoMapper;

    @Override
    public LoginUserInfoDTO login(String userName, String password) {

        LambdaQueryWrapper<SysUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        lambdaQueryWrapper.eq(SysUser::getUserName,userName);

        List<SysUser> userList = sysUserMapper.selectList(lambdaQueryWrapper);

        if (userList.isEmpty()){
            throw new SelfException(500,"账号或密码错误！");
        }

        SysUser sysUser = userList.get(0);

        if (!Objects.equals(sysUser.getPassword(),password)){
            throw new SelfException(500,"账号或密码错误！");
        }

        LoginUserInfoDTO loginUserInfoDTO = new LoginUserInfoDTO();

        String token = JwtUtils.sign(userName);

        loginUserInfoDTO.setToken(token);
        loginUserInfoDTO.setUserId(sysUser.getUserId().toString());
        loginUserInfoDTO.setUserName(sysUser.getUserName());
        loginUserInfoDTO.setUserType(sysUser.getUserType());
        loginUserInfoDTO.setImgUrl(sysUser.getImgUrl());
        loginUserInfoDTO.setUserType(sysUser.getUserType());
        if (Objects.nonNull(sysUser.getLastLoginTime())){
            loginUserInfoDTO.setLastLoginTime(DateUtil.format(sysUser.getLastLoginTime(),"yyyy-MM-dd HH:mm:ss"));
        }

        sysUser.setLastLoginTime(new Date());

        sysUserMapper.updateById(sysUser);

        ShopInfo shopInfo = shopInfoMapper.selectShopInfoByUserId(sysUser.getUserId());

        if (Objects.nonNull(shopInfo)){
            loginUserInfoDTO.setShopId(shopInfo.getShopId());
        }

        return loginUserInfoDTO;

    }

    @Override
    public RegisterUserRepDTO registerUser(RegisterUserReqDTO registerUserReqDTO) {

        RegisterUserRepDTO result = new RegisterUserRepDTO();

        LambdaQueryWrapper<SysUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        lambdaQueryWrapper.eq(SysUser::getUserName,registerUserReqDTO.getUserName());

        List<SysUser> userList = sysUserMapper.selectList(lambdaQueryWrapper);

        if (!userList.isEmpty()){

            throw new SelfException(500,"用户名已存在");

        }

        lambdaQueryWrapper = new LambdaQueryWrapper<>();

        lambdaQueryWrapper.eq(SysUser::getPhone,registerUserReqDTO.getPhone());

        userList = sysUserMapper.selectList(lambdaQueryWrapper);

        if (!userList.isEmpty()){

            throw new SelfException(500,"该号码已被注册");

        }

        SysUser sysUser = new SysUser();

        BeanUtils.copyProperties(registerUserReqDTO,sysUser);

        sysUser.setBirthday(DateUtil.parse(registerUserReqDTO.getBirthday(),"yyyy-MM-dd"));

        sysUser.setPassword(PasswordUtils.encrypt(Base64.decodeStr(registerUserReqDTO.getPassword())));

        sysUser.setStatus(UserStatusEnum.ENABLE.getCode());
        sysUser.setUserType(UserTypeEnum.SHOP.getCode());

        sysUser.setVipLevel(1);
        sysUser.setCreateTime(new Date());
        sysUser.setUpdateTime(new Date());
        sysUser.setCreateByName("admin");
        sysUser.setUpdateByName("admin");

        sysUserMapper.insert(sysUser);

        result.setUserName(sysUser.getUserName());
        result.setPassword(Base64.decodeStr(registerUserReqDTO.getPassword()));

        return result;

    }

    @Override
    public JudgeSingleRepDTO judgeSingle(JudgeSingleReqDTO judgeSingleReqDTO) {

        JudgeSingleRepDTO result= new JudgeSingleRepDTO();

        if (Objects.nonNull(judgeSingleReqDTO.getUserName())&&!Objects.equals(judgeSingleReqDTO.getUserName(),"")){

            LambdaQueryWrapper<SysUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();

            lambdaQueryWrapper.eq(SysUser::getUserName,judgeSingleReqDTO.getUserName());

            List<SysUser> userList = sysUserMapper.selectList(lambdaQueryWrapper);

            if (!userList.isEmpty()){

                result.setUserNameFlag(true);

            }else {
                result.setUserNameFlag(false);
            }
        }else {
            result.setUserNameFlag(false);
        }

        if (Objects.nonNull(judgeSingleReqDTO.getPhone())&&!Objects.equals(judgeSingleReqDTO.getPhone(),"")){

            LambdaQueryWrapper<SysUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();

            lambdaQueryWrapper.eq(SysUser::getPhone,judgeSingleReqDTO.getPhone());

            List<SysUser> userList = sysUserMapper.selectList(lambdaQueryWrapper);

            if (!userList.isEmpty()){

                result.setPhoneFlag(true);

            }else {
                result.setPhoneFlag(false);
            }
        }{
            result.setPhoneFlag(false);
        }

        return result;
    }

    @Override
    public void changePassword(PasswordChangeDTO passwordChangeDTO) {

        String oldPas = PasswordUtils.encrypt(Base64.decodeStr(passwordChangeDTO.getOldPassword()));

        SysUser loginUser = (SysUser) SecurityUtils.getSubject().getPrincipal();

        if (!Objects.equals(loginUser.getPassword(),oldPas)){
            throw new SelfException(ResponseCodeEnum.SYS_ERROR.getCode(), "原密码错误");
        }

        loginUser.setPassword(PasswordUtils.encrypt(Base64.decodeStr(passwordChangeDTO.getPassword())));

        sysUserMapper.updateById(loginUser);

    }

}
